/**
 * 
 */
package edu.bu.grocery.backingbean;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import edu.bu.grocery.session.UserSession;
import edu.bu.grocerylist.model.GroceryUser;
import edu.bu.grocerylist.service.IGroceryUserService;

/**
 * BackingBean for reset password functionality
 * 
 * @author donlanp
 * 
 */
public class ResetPasswordBackingBean implements Serializable {

	private static final long serialVersionUID = -4398767038002890693L;

	private UserSession session;
	private IGroceryUserService userService;

	private GroceryUser userCheck;

	private String username;
	private String securityAnswer;

	private String password;
	private String confirmPassword;

	/**
	 * First step of password reset, we obtain the user's information
	 * 
	 * @return If we successfully obtain a user, we proceed to the next page.
	 */
	public String getUserInformation() {
		// Perform validation of input
		if (username == null || username.isEmpty()) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("Please input a username!"));
			return "";
		}

		userCheck = userService.getUserSecurityQuestion(username);
		if (userCheck == null) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("That user does not exist!"));
			return "";
		}
		// Reset information
		username = "";

		return "securityquestion";

	}

	/**
	 * A user answer's their security question, and we verify it is correct.
	 * 
	 * @return If the question is correct, we continue to the reset password
	 *         screen.
	 */
	public String checkSecurityAnswer() {
		System.out.println(securityAnswer + " :: "
				+ userCheck.getSecurityAnswer());
		if (securityAnswer == null || securityAnswer.isEmpty()) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("Please input your answer!"));
			return "";
		}

		if (!securityAnswer.equals(userCheck.getSecurityAnswer())) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("Incorrect answer!"));
			return "";

		}
		// Reset information
		securityAnswer = "";
		System.out.println("Success!");

		return "confirmpassword";
	}

	/**
	 * User enters in a new password, we perform validation, and ensure that the
	 * user fills in all fields correctly
	 * 
	 * @return If everything checks out, we reset the password and login in the
	 *         user
	 */
	public String resetPassword() {
		// Perform validation
		if (password == null || password.isEmpty()) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("Please input your password!"));
			return "";
		}

		if (confirmPassword == null || confirmPassword.isEmpty()) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("Please input your password!"));
			return "";
		}

		// Check if the new information matches
		if (!password.equals(confirmPassword)) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("Passwords do not match!"));
			return "";

		}

		// Validate password
		boolean foundUpper = false;
		boolean foundLower = false;
		boolean foundNumber = false;

		for (Character c : password.toCharArray()) {
			if (Character.isUpperCase(c)) {
				foundUpper = true;
			}
			if (Character.isLowerCase(c)) {
				foundLower = true;
			}
			if (Character.isDigit(c)) {
				foundNumber = true;
			}
		}

		if (!foundUpper || !foundLower || !foundNumber || password.length() < 8) {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									"Please enter a correct password (must contain upper and lower case and at least 8 characters)!"));
			return "";

		}

		GroceryUser updated = userService.updatePassword(userCheck, password);
		session.setCurrentUser(updated);

		// Reset information
		password = "";
		confirmPassword = "";

		return "login";
	}

	// Getters and Setters

	/**
	 * @return the userService
	 */
	public IGroceryUserService getUserService() {
		return userService;
	}

	/**
	 * @param userService
	 *            the userService to set
	 */
	public void setUserService(IGroceryUserService userService) {
		this.userService = userService;
	}

	/**
	 * @return the session
	 */
	public UserSession getSession() {
		return session;
	}

	/**
	 * @param session
	 *            the session to set
	 */
	public void setSession(UserSession session) {
		this.session = session;
	}

	/**
	 * @return the userCheck
	 */
	public GroceryUser getUserCheck() {
		return userCheck;
	}

	/**
	 * @param userCheck
	 *            the userCheck to set
	 */
	public void setUserCheck(GroceryUser userCheck) {
		this.userCheck = userCheck;
	}

	/**
	 * @return the userName
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param userName
	 *            the userName to set
	 */
	public void setUsername(String userName) {
		this.username = userName;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password
	 *            the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the securityAnswer
	 */
	public String getSecurityAnswer() {
		return securityAnswer;
	}

	/**
	 * @param securityAnswer
	 *            the securityAnswer to set
	 */
	public void setSecurityAnswer(String securityAnswer) {
		this.securityAnswer = securityAnswer;
	}

	/**
	 * @return the confirmPassword
	 */
	public String getConfirmPassword() {
		return confirmPassword;
	}

	/**
	 * @param confirmPassword
	 *            the confirmPassword to set
	 */
	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

}
